今天來到了介紹Generator(生成器),過去我們有介紹列表推導式,但其實dict、set也都可以用推導式的寫法,但是唯獨tuple很特別。
今天如果我們這樣寫(i for i in range(0, 11))
把這串印出來,他就會是一個生成器<generator object <genexpr> at 0x102769270>
,生成器有兩個特點
It looks like a normal function except that it contains yield expressions for producing a series of values usable in a for-loop or that can be retrieved one at a time with the next() function. - 「3.10.6 Python Documentation」
我們馬上用程式驗證看看以上兩個特點:
a = (i for i in range(0, 11))
for i in (1, 2):
for j in a:
print(j)
我把上面生成器的範例取出資料的動作重複做兩次,也確實只能取出一次資料,那我們接著再試看看,宣告一個方法裡面加上yield
def gen():
yield 123
print(gen()) # <generator object gen at 0x10278e270>
加上yield的方法也確實是生成器,但是卻不清楚yield做什麼的嗎? 從上面生成器的定義看起來感覺跟next()有點關係,那我們就用生成器搭配next()再試看看
def gen():
yield 123
yield 456
yield 789
g = gen()
print(next(g)) # 123
print(next(g)) # 456
print(next(g)) # 789
可是我之前只介紹有next()卻沒有說他是幹嘛的嗎?
Retrieve the next item from the iterator by calling its next() method. If default is given, it is returned if the iterator is exhausted, otherwise StopIteration is raised. - 「3.10.6 Python Documentation
根據官方文件對next的描述,我們可以了解next()其實是幫助我們從生成器或者是迭代器中一直取出下一個資料,直到資料全部被取出。
那上面這個例子其實就可以很清楚的了解,yield能夠記住當下取得的部分,每呼叫一次next他會繼續往下取值。
最後分享一下我的心得,過去我在還沒有了解迭代器或者是生成器的時候,踩了滿多坑,也常常print出來是把迭代器或者是生成器物件印出來,卻發現沒有值,在了解之後可能還不是到很厲害,但是起碼你對這個概念有稍微認識,不至於到很陌生,通常對於越陌生的東西,我們就會感到越害怕,所以雖然我介紹的東西
可能不實用,但是認識它,你絕對不會有損失。
明天我要接著來分享一下字串格式化